﻿using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Text;

namespace ChatGPT.UI;

public class ChatGPTClient
{
    public string ApiKey = "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";
    private string baseUrl = "https://api.openai.com";
    private readonly ILogger logger;

    public ChatGPTClient(ILoggerFactory loggerFactory)
    {
        // logger = loggerFactory.CreateLogger("monitor.gpt");
    }

    public async Task<string> Models()
    {
        try
        {
            using var client = new HttpClient();
            client.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
            var content = await client.GetStringAsync($"{baseUrl}/v1/models");
            logger?.LogInformation(content);
            return content;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return ex.Message;
        }
    }

    public Task<CompletionResult> SendText(string user, string content) =>
        SendText(user, new List<CompletionMessage> {
            new CompletionMessage {
                Role = "user",
                Content = content
            }
        });

    public async Task<CompletionResult> SendText(string user, List<CompletionMessage> messages)
    {
        var result = await PostJson($"{baseUrl}/v1/chat/completions", new
        {
            model = "gpt-3.5-turbo-0613",
            user,
            messages,
        });

        return JsonConvert.DeserializeObject<CompletionResult>(result);
    }

    public async Task<string> GetCompletion(string prompt)
    {
        var result = await PostJson($"{baseUrl}/v1/chat/completions", new
        {
            model = "gpt-3.5-turbo-0613",
            messages = new[] {
                new {
                    role = "user",
                    content=prompt,
                }
            }
        });
        return result;
    }
    public async Task<string> GetCompletion(string system, string prompt)
    {
        var result = await PostJson($"{baseUrl}/v1/chat/completions", new
        {
            model = "gpt-3.5-turbo-16k-0613",
            messages = new[] {
                new {
                role ="system",
                content =system
                },
                new {
                    role = "user",
                    content=prompt,
                }
            }
        });
        return result;
    }
    private async Task<string> PostJson(string url, object data)
    {
        try
        {
            using var client = new HttpClient();
            client.Timeout = TimeSpan.FromSeconds(600);
            client.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
            var json = JsonConvert.SerializeObject(data);
            logger?.LogInformation(json);
            Console.WriteLine(url);
            var request = new HttpRequestMessage(HttpMethod.Post, url);
            request.Content = new StringContent(json, Encoding.UTF8, "application/json");
            var response = await client.SendAsync(request);
            var content = await response.Content.ReadAsStringAsync();
            logger?.LogInformation(content);
            return content;
        }
        catch (Exception ex)
        {
            logger?.LogError(ex.Message);
            throw;
        }
    }

}


public class CompletionMessages : List<CompletionMessage>
{
}

public class CompletionMessage
{
    [JsonProperty("content")]
    public string Content { get; set; }
    [JsonProperty("role")]
    public string Role { get; set; }
}

public class CompletionResult
{
    public ErrorMessage Error { get; set; }
    public class ErrorMessage
    {
        public string Message { get; set; }
    }

    public UsageTokens Usage { get; set; }
    public class UsageTokens
    {
        public int prompt_tokens { get; set; }
        public int completion_tokens { get; set; }
        public int total_tokens { get; set; }
    }
    public List<Choice> Choices { get; set; }
    public class Choice
    {
        public Message Message { get; set; }
    }


    public class Message
    {
        public string Role { get; set; }
        public string Content { get; set; }
    }
}
